//
//  ST_TianSessionInfoProvider.swift
//  btvideo
//
//  Created by mac on 2021/7/6.
//  Copyright © 2021 JarvanZhang. All rights reserved.
//

import UIKit
import Alamofire
import NIMSDK
import Cache
import RxCocoa
import RxSwift






struct ST_BTUserInfoFromRemote {
    var accid:String
    var avatar:String
    var userName:String
}

let BINP = ST_NIMSessionListInfoProvider.shared

class ST_NIMSessionListInfoProvider {
    
    static let shared = ST_NIMSessionListInfoProvider()
    
    private init(){}
    
    let diskConfig = DiskConfig(name: "Floppy")
    let memoryConfig = MemoryConfig()

    lazy var storage = try? Storage<String, ST_ConversationSummarryCacheStruct>(
      diskConfig: diskConfig,
      memoryConfig: memoryConfig,
      transformer: TransformerFactory.forCodable(ofType: ST_ConversationSummarryCacheStruct.self) // Storage<String, User>
    )
    /// 贵族临时缓存
    fileprivate lazy var nobleStorage = try? Storage<String, ST_NobleTemporary>(
      diskConfig: DiskConfig(name: "FloppyKKKK01"),
      memoryConfig: MemoryConfig(),
      transformer: TransformerFactory.forCodable(ofType: ST_NobleTemporary.self)
    )
    /// 女神Accid 缓存
    private var goddess_cache = Set<String>()
    
    /// 任务分块 size
    fileprivate let chunk_size = 30
    
    /// 单一任务延迟时间
    fileprivate let single_delay_seconds:Double = 4
    
    /// 已经创建的请求
    fileprivate var data_request_set = Set<DataRequest>()
    /// 准备创建请求的延时任务
    fileprivate var prepare_work_item_set = [DispatchWorkItem]()
    
    fileprivate lazy var requestQueue = DispatchQueue(label: "tian.session.info.queue")
    
    /// 更新
    let update_displaying_subject = BehaviorSubject<Void>(value: ())
    
}
extension ST_NIMSessionListInfoProvider{
    
    fileprivate func create_task(idString:String,mainQueue:Bool = false){
                                
//        var test : Weak<ST_ConversationAdapterUIUpdateDelegate>
        
        
        let param = ["accids":idString]
        
        let queue = mainQueue ? DispatchQueue.main : requestQueue
        
        
        print("【NIM allRecentSessions】request ids =",idString)
        
        let request = TIANRequest(PH.usersProfileListApi,parameters: param,queue: queue, success: { (json) in
          
            
            var personalGuard = Set<String>()
            
            json["data"].arrayValue.forEach { (itemJson) in
                 
                 let currId = itemJson["accid"].stringValue
                 
                 var isVip = false
                 
                 if !SYSTEM_SESSION_SET.contains(currId){
                     isVip = CHECK_MEMBER_STATUS(expirationTime: itemJson["vip_expire"].intValue) == .subscribe
                 }
                
                
                var img:String?
                if let imgUrl = itemJson["intimacy_image"].string,imgUrl.count > 1{
                    img = imgUrl
                }
                  
                let cacheItem = ST_ConversationSummarryCacheStruct.init(sessionId: currId, headPic: itemJson["avatar"].stringValue, userName: itemJson["nickname"].stringValue, remark: itemJson["remark"].stringValue, isGoddess: itemJson["is_goddess"].boolValue, face_audit_state: itemJson["face_audit_state"].intValue, isVip: isVip,nobilityImg:itemJson["nobility"]["image"].string, guardTime: itemJson["guard_time"].intValue, guardContent: itemJson["guard_content"].stringValue,guardTop:itemJson["guard_top"].boolValue, source: itemJson["source"].intValue,sweetValueImage:img,online_state: itemJson["hb_status"].stringValue)
                
                try? self.storage?.setObject(cacheItem, forKey: cacheItem.sessionId)
                
                if cacheItem.guardTop{
                    personalGuard.update(with: currId)
                }
                 
             }
            
            
            if Thread.current.isMainThread && personalGuard.count > 0{
                
                print("拉取多个数据主线程 && 第一次 更新守护 并排序")
                
                ST_ConversationAdapter.shared.sortBy(guardIds: personalGuard)
                
            }
            
            main_thread_execute(afterDelay: 1) {
                
                print("拉取多个数据 更新展示样式")
                
                self.update_displaying_subject.onNext(())
                
//                self.delegate?.update_displaying_cells_data()
            }
            
         }) { (code, error) in
            
         }
        
        guard let req = request else { return  }
        
        data_request_set.update(with: req)
    }
    
}

extension ST_NIMSessionListInfoProvider{
    
    func createPullTask(sessions:[ST_TianSessionSummaryStruct],isFirst:Bool = false){
        
        let ids = sessions.map{ $0.sessionId }.filter{
            
            (try? storage?.existsObject(forKey: $0)) ?? false == false
            
        }
        
        let group = ids.chunked(into: chunk_size).map{ $0.joined(separator: ",") }
        
        for (idx,item) in group.enumerated() {
            
            
            /// 当前账号第一次请求后台数据
            if isFirst{
                
                create_task(idString: item, mainQueue: true)
                
            }else{
                
                let workItem = DispatchWorkItem {
                    self.create_task(idString: item)
                }
                
                let delay = DispatchTime.now() + idx.double * single_delay_seconds
                
                requestQueue.asyncAfter(deadline: delay, execute: workItem)
                
                prepare_work_item_set.append(workItem)
            }
        }
        
    }
    
    func clearTask(){
        
        /// 取消已经发出的请求
        data_request_set.forEach{ $0.cancel() }
        
        data_request_set.removeAll()
        
        /// 取消 创建请求的延时任务
        prepare_work_item_set.forEach{ $0.cancel() }
        
        prepare_work_item_set.removeAll()
        
        try? storage?.removeAll()
        
    }
    
}


extension ST_NIMSessionListInfoProvider{
    
    func update_friend_remark(id:String,remark:String){
        
        guard let item = try? storage?.object(forKey: id) else { return  }
        
        let updateItem = ST_ConversationSummarryCacheStruct.init(sessionId: item.sessionId, headPic: item.headPic, userName: item.userName, remark: remark, isGoddess: item.isGoddess, face_audit_state: item.face_audit_state, isVip: item.isVip,nobilityImg:item.nobilityImg, guardTime: item.guardTime, guardContent: item.guardContent,guardTop:item.guardTop, source: item.source,sweetValueImage:item.sweetValueImage,online_state: item.online_state)
        
        try? storage?.setObject(updateItem, forKey: id)
        
//        self.delegate?.update_displaying_cells_data()
        
//        self.delegates.forEach({ ($0.value as? ST_ConversationAdapterUIUpdateDelegate)?.update_displaying_cells_data() })
        
        self.update_displaying_subject.onNext(())
    }
    
    func update_friend_avatar(id:String,url:String){
        
        guard let item = try? storage?.object(forKey: id) else { return  }
        
        let updateItem = ST_ConversationSummarryCacheStruct.init(sessionId: item.sessionId, headPic: url, userName: item.userName, remark: item.remark, isGoddess: item.isGoddess, face_audit_state: item.face_audit_state, isVip: item.isVip,nobilityImg:item.nobilityImg, guardTime: item.guardTime, guardContent: item.guardContent,guardTop:item.guardTop, source: item.source,sweetValueImage:item.sweetValueImage,online_state: item.online_state)
        
        try? storage?.setObject(updateItem, forKey: id)
        
//        self.delegate?.update_displaying_cells_data()
        
//        self.delegates.forEach({ ($0.value as? ST_ConversationAdapterUIUpdateDelegate)?.update_displaying_cells_data() })
        
        self.update_displaying_subject.onNext(())
    }
    
    
    func update_base_info(remoteInfo:ST_BTUserInfoFromRemote){
        
        if let item = try? storage?.object(forKey: remoteInfo.accid)  {
        
            let updateItem = ST_ConversationSummarryCacheStruct.init(sessionId: item.sessionId, headPic: remoteInfo.avatar, userName: remoteInfo.userName, remark: item.remark, isGoddess: item.isGoddess, face_audit_state: item.face_audit_state, isVip: item.isVip,nobilityImg:item.nobilityImg, guardTime: item.guardTime, guardContent: item.guardContent,guardTop:item.guardTop, source: item.source,sweetValueImage:item.sweetValueImage,online_state: item.online_state)
            
            try? storage?.setObject(updateItem, forKey: remoteInfo.accid)
        
        }else{
            
            let newItem = ST_ConversationSummarryCacheStruct.init(sessionId: remoteInfo.accid, headPic: remoteInfo.avatar, userName: remoteInfo.userName, remark: "", isGoddess: false, face_audit_state: 0, isVip: false,nobilityImg:nil, guardTime: 0, guardContent: "",guardTop:false, source: 0,sweetValueImage:"",online_state: "")
            
            try? storage?.setObject(newItem, forKey: remoteInfo.accid)
        }
    }
    
    func fetch_nickname_with_avatar(userId:String) -> ST_BTUserInfoFromRemote? {
        
        guard let item = try? storage?.object(forKey: userId)  else{
            return nil
        }
        
        
        return ST_BTUserInfoFromRemote(accid: item.sessionId, avatar: item.headPic, userName: item.userName)
    }
}


extension ST_NIMSessionListInfoProvider{
    /// 获取贵族聊天文字效果
    func fetch_noble_effect(accid:String)->GradientEffectStruct?{
        
        /// 自己是女 隐藏贵族的时候
        if let user = ST_BTUserInfoManager.shared.current_account_info?.userinfo,user.accid == accid,user.sex == .female,ST_BTUserInfoManager.shared.additional_attributes?.myNobilityHid == true{
            return nil
        }
        
        guard let n = try? nobleStorage?.object(forKey: accid) else{return nil}
        
        return GradientEffectStruct.effectGenerator(noble: n)
        
    }
    
    /// 保存用户贵族信息
    func save_gradient_effect_struct(accid:String,nobleLevel:Int,nobleUrl:String){
        
        try? nobleStorage?.setObject(ST_NobleTemporary(id: nobleLevel, url: nobleUrl), forKey: accid)
    }
    
}



extension ST_NIMSessionListInfoProvider{
    
    func check_goddess(accid:String)->Bool{
        
        if accid == ST_BTUserInfoManager.shared.current_account_info?.accid , let addValue = ST_BTUserInfoManager.shared.additional_attributes,addValue.isGoddess{
            return true
        }
        
        return goddess_cache.contains(accid)
        
    }
    
    /// 用户女神信息更新
    func update_goddess(accid:String,isGoddess:Bool = true){
        
        if isGoddess{
            goddess_cache.update(with: accid)
        }else{
            goddess_cache.remove(accid)
        }
    }
    
}



//MARK: -
struct ST_NobleTemporary:Codable {
    let id:Int
    let url:String
}
